/*
    根据阈值独立进行ddr3的执行
*/
module wr0 #(
    parameter
        FRAME_ROW     = 16'd480, // 一帧的行数
        FRAME_LINE    = 16'd640, // 一帧的列数，16bit为一个单位
        WR0_BURST_LEN = 16'd160, // wr0_fifo一次突发要突发的长度，
        WR0_THRESHOLD = 16'd160  // wr0驱动ddr写的阈值——1行数据
)(
    input               clk                     ,
    input               rst_n                   ,
    //------------ fifo 接口 ---------------------
    input               wr0_wr_clk              ,
    input               wr0_rd_clk              ,
    input      [ 7:0]   wr0_8bit_din            ,
    input               wr0_wr_en               ,
    output     [ 8:0]   wr0_9bit_rd_cnt         ,
    //------------ ddr3 接口----------------------
    input               input_fifo_rd_en        ,
    input               wr_done                 ,
    output reg [ 24:0]  begin_addr              ,
    output              rw                      ,
    output reg [  1:0]  mask_switch             ,
    output     [127:0]  wr_data                 ,
    output     [ 15:0]  burst_data_len          ,
    output reg          exc                     ,
    output reg          first_frame_wr_done     
);
// parameters
reg  [15:0] row_cnt;
wire [63:0] wr0_64bit_dout;
wire        wr0_rd_en;
//------------------------------ main code -------------------------
assign wr0_rd_en = input_fifo_rd_en;
//---------------- 前置操作 ----------------
// 已写入的行，行计数
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        row_cnt <= 16'd0;
    else if((row_cnt == FRAME_ROW - 16'd1) && wr_done)             // 写满了一帧，计数复位
        row_cnt <= 16'd0;
    else if(wr_done)
        row_cnt <= row_cnt + 16'd1;
    else 
        row_cnt <= row_cnt;
end

//---------------- 信号输出 ----------------
// begin_addr
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        begin_addr <= 25'd0;
    else if(wr_done && (row_cnt == FRAME_ROW - 16'd1)) // 写满了一帧，地址复位
        begin_addr <= 25'd0;
    else if(wr_done)           
        begin_addr <= begin_addr + (FRAME_LINE << 1);
    else 
        begin_addr <= begin_addr;
end

// rw
assign rw = 1'd0;           // 写操作

// exc
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        exc <= 1'd0;
    else if(wr0_9bit_rd_cnt >= WR0_THRESHOLD)
        exc <= 1'd1;
    else 
        exc <= 1'd0;
end

// mask_switch
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        mask_switch <= 2'b10;                            // 默认写低64位
    else if(wr_done && (row_cnt == FRAME_ROW - 16'd1))   // 写满了一帧，掩码转换
        mask_switch <= ~mask_switch;
    else
        mask_switch <= mask_switch;
end

// wr_data
assign wr_data = (mask_switch == 2'b10) ? {{64{1'd0}}, wr0_64bit_dout} : {wr0_64bit_dout, {64{1'd0}}};

// burst_data_len
assign burst_data_len = WR0_BURST_LEN;  

// first_frame_wr_done
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        first_frame_wr_done <= 1'd0;
    else if(wr_done && (row_cnt == FRAME_ROW - 16'd1))
        first_frame_wr_done <= 1'd1;
    else
        first_frame_wr_done <= first_frame_wr_done;
end
// wr0_fifo-------------------------
wr0_fifo_4096x8_512x64 u_wr0_fif0(
    .rst          (~rst_n           ),       // input wire rst
    .wr_clk       (wr0_wr_clk       ),       // input wire wr_clk
    .rd_clk       (wr0_rd_clk       ),       // input wire rd_clk
    .din          (wr0_8bit_din     ),       // input wire [7 : 0] din
    .wr_en        (wr0_wr_en        ),       // input wire wr_en
    .rd_en        (wr0_rd_en        ),       // input wire rd_en
    .dout         (wr0_64bit_dout   ),       // output wire [63 : 0] dout
    .full         (                 ),       // output wire full
    .empty        (                 ),       // output wire empty
    .rd_data_count(wr0_9bit_rd_cnt  ),       // output wire [8 : 0] rd_data_count
    .wr_rst_busy  (                 ),       // output wire wr_rst_busy
    .rd_rst_busy  (                 )        // output wire rd_rst_busy
);
endmodule